package com.achao.achaomq.aop;

import com.achao.achaomq.annotation.ApiMonitorAnnotation;
import com.achao.achaomq.constants.RocketMqConstant;
import com.achao.achaomq.service.RocketMqService;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;
import java.util.HashMap;

/**
 * @Description：接口监控-统计 实现
 * @date：2024/7/21 21:20
 */
@Aspect
@Component
public class ApiMonitorAop {
    private static final Logger logger = LoggerFactory.getLogger(ApiMonitorAop.class);

    @Autowired
    private RocketMqService rocketMqService;

    /**
     * 拦截指定注解
     */
    @Pointcut("@annotation(com.achao.achaomq.annotation.ApiMonitorAnnotation)")
    public void monitorResponseTime() {}

    /**
     * 拦截器具体实现
     *
     * @param pjp
     */
    @Around("monitorResponseTime()")
    public Object interceptor(ProceedingJoinPoint pjp) throws Throwable {
        //记录开始时间
        Long beginTime = System.currentTimeMillis();
        ApiMonitorAnnotation annotation = getAnnotationFromJoinPoint(pjp);
        Object proceed = pjp.proceed();

        //记录结束时间
        long endTime = System.currentTimeMillis();
        logger.info(String.format("接口响应统计:接口模块%s-接口编码：%s 接口名称：%s 请求服务器用时(毫秒):%s",
                annotation.apiModel(),
                annotation.apiCode(),
                annotation.apiName(),
                String.valueOf(endTime - beginTime)));

        //MQ记录日志
        rocketMqService.sendRocketMQ(
                getMqParam(annotation.apiModel(),annotation.apiCode(),annotation.apiName(),endTime - beginTime),
                RocketMqConstant.ACHAO_LOG_RECORD,
                "RocketMQ异步日志记录"
        );

        return proceed;
    }

    /**
     * 从切点获取接口响应注解
     *
     * @param pjp
     * @return
     */
    private ApiMonitorAnnotation getAnnotationFromJoinPoint(ProceedingJoinPoint pjp) {
        Signature signature = pjp.getSignature();
        MethodSignature methodSignature = (MethodSignature) signature;
        Method method = methodSignature.getMethod();
        return method.getAnnotation(ApiMonitorAnnotation.class);
    }

    //组装mq需要的参数
    private HashMap<String,Object> getMqParam(String apiModel,String apiCode,String apiName,long timeConsumption){
        HashMap<String,Object> map = new HashMap();
        map.put("apiModel",apiModel);
        map.put("apiCode",apiCode);
        map.put("apiName",apiName);
        map.put("timeConsumption",timeConsumption);
        return map;
    }
}
